package com.ycb.service;

import com.alibaba.nacos.common.utils.DateFormatUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycb.entity.Goods;
import com.ycb.entity.Order;
import com.ycb.feign.GoodsClient;
import com.ycb.feign.UserClient;
import com.ycb.mapper.OrderMapper;
import com.ycb.utils.TCCUtil;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * @author 黄泽群
 * @since 2023-12-11
 */
@Slf4j
@Service
@LocalTCC
@RequiredArgsConstructor
public class OrderService extends ServiceImpl<OrderMapper, Order> {

    private final UserClient userClient;
    private final GoodsClient goodsClient;


    @Transactional // 单数据源内部可以通过Transactional保证单节点事务
    @TwoPhaseBusinessAction(name = "create",commitMethod = "createCommit",rollbackMethod = "createRollback",isDelayReport = true,useTCCFence = true)
    public Order create(BusinessActionContext context,
                        @BusinessActionContextParameter("userId") Integer userId,
                        @BusinessActionContextParameter("goodsId") Integer goodsId,
                        @BusinessActionContextParameter("qty") Integer qty) {
        log.warn("inGlobalTransaction:{} context:{}",RootContext.inGlobalTransaction(),context);
        Goods goods = goodsClient.subStock(goodsId, qty);
        int totalAmt = goods.getPrice() * qty;
        Order order = new Order();
        order.setCode(DateFormatUtils.format(new Date(),DateFormatUtils.YYYYMMDDHHMMSSNOMARK));
        order.setAmt(totalAmt);
        order.setQty(qty);
        order.setGoodsId(goodsId);
        order.setUserId(userId);
        super.save(order);
        TCCUtil.put(context.getXid(),"orderId",order.getId());
        userClient.subAmount(userId,totalAmt);
        return order;
    }

    public void createCommit(BusinessActionContext context){
        log.warn(" createCommit xid :{} branchId:{} userId:{} goodsId:{} qty:{}",context.getXid(),context.getBranchId()
                ,context.getActionContext("userId"),context.getActionContext("goodsId"),context.getActionContext("qty") );
        String xid = context.getXid();
    }

    public void createRollback(BusinessActionContext context){
        log.warn(" createRollback xid :{} branchId:{} userId:{} goodsId:{} qty:{} orderId:{} {}",context.getXid(),context.getBranchId()
                ,context.getActionContext("userId"),context.getActionContext("goodsId"),context.getActionContext("qty"),
                context.getActionContext("orderId"),context);
        String xid = context.getXid();
        try{
            super.lambdaUpdate().eq(Order::getId,TCCUtil.getParams(xid,"orderId")).remove();
        }finally {
            TCCUtil.remove(xid);
        }
    }


}
